package com.zhoug.common3.utils.zip;

import com.zhoug.common3.utils.IOUtils;
import com.zhoug.common3.utils.LogUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**
 * 压缩解压工具
 * @Author 35574
 * @Date 2021/3/18
 * @Description
 */
public class ZipUtils1  {
    private static final String TAG = ">>>ZipUtils";
    private static final boolean DEBUG = false;

    /**
     * 解压zip文件
     * @param srcFile zip文件
     * @param desFile 解压后的文件
     */
    public static void unZip(File srcFile, File desFile) throws Exception {
        if (srcFile == null || !srcFile.exists()) {
            throw new IllegalArgumentException("zip文件不存在");
        }
        if (desFile == null) {
            throw new IllegalArgumentException("desFile is null");
        }
        mkdirs(desFile);
        if (DEBUG) {
            LogUtils.d(TAG, "##############开始解压:" + srcFile.getAbsolutePath());
        }
        ZipInputStream zipInputStream = null;
        try {
            ZipFile zipFile = getZipFile(srcFile);
            zipInputStream = new ZipInputStream(new FileInputStream(srcFile));
            ZipEntry zipEntry = null;
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                zipEntry = entries.nextElement();
                String fileName = zipEntry.getName();
                File temp = new File(desFile, fileName);
                if (DEBUG) {
                    LogUtils.d(TAG, "temp:" + temp);
                }
                //文件夹
                if (zipEntry.isDirectory()) {
                    mkdirs(temp);
                    continue;
                }
                //创建父目录
                mkdirs(temp.getParentFile());
                InputStream is = zipFile.getInputStream(zipEntry);
                OutputStream os = new FileOutputStream(temp);
                IOUtils.copy(is, os);
            }
            if (DEBUG) {
                LogUtils.d(TAG, "##############解压完成###########");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.close(zipInputStream);
        }
    }

    private static ZipFile getZipFile(File zipFile) throws Exception {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            List<Charset> allCharset = getAllCharset();
            ZipFile zip=null;
            for (int i = 0; i < allCharset.size(); i++) {
                Charset charset = allCharset.get(i);
                try {
                    if (DEBUG) {
                        LogUtils.d(TAG, "charset:" + charset);
                    }
                    zip = new ZipFile(zipFile, charset);
                    Enumeration<?> entries = zip.entries();
                    if (entries.hasMoreElements()) {
                        entries.nextElement();
                        zip.close();
                        zip=null;
                        return new ZipFile(zipFile, charset);
                    }
                } catch (Exception e) {
//                    e.printStackTrace();
                }finally {
                    if(zip!=null){
                        zip.close();
                    }
                }
            }
        }
        if (DEBUG) {
            LogUtils.d(TAG, "没有找到zip编码方式:");
        }
        return new ZipFile(zipFile);
    }

    private static List<Charset> getAllCharset() {
        return Arrays.asList(
                StandardCharsets.UTF_8,Charset.forName("GBK"), StandardCharsets.ISO_8859_1, StandardCharsets.US_ASCII,
                StandardCharsets.UTF_16, StandardCharsets.UTF_16BE, StandardCharsets.UTF_16LE

        );
    }

    /**
     * 创建文件夹
     *
     * @param file
     * @throws IOException
     */
    private static void mkdirs(File file) throws IOException {
        if (file != null && !file.exists()) {
            if (!file.mkdirs()) {
                throw new IOException("创建文件夹失败:" + file.getAbsolutePath());
            }
        }
    }

}
